Imports Microsoft.DirectX.Direct3D

Namespace MessageBoxes

    Module mMessageBoxes

        Public WithEvents msg As GUI.MirWindow
        Public WithEvents btnOK As GUI.MirButton
        Public WithEvents btnYes As GUI.MirButton
        Public WithEvents btnNo As GUI.MirButton

        Public WithEvents txtInput As GUI.MirTextBox

        Public Sub Init()

            With Libs.GameInter

                rText = New Rectangle(25, 30, 258, 103) '284, 135)

                rStateText = New Rectangle(35, 38, .Image(664).Header.Width - 70, .Image(664).Header.Height - 76)

                msg = New GUI.MirWindow("MessageBox", , , .Image(421).Header.Width, .Image(421).Header.Height)
                btnOK = New GUI.MirButton(msg, "btnOk", (.Image(421).Header.Width \ 2) - (.Image(424).Header.Width \ 2), 145, 0.01F, EvoLib.Protocol.ImgLibs.GameInter, 424, 424, 425, , False)
                btnYes = New GUI.MirButton(msg, "btnYes", (.Image(421).Header.Width \ 4) - (.Image(422).Header.Width \ 2), 145, 0.01F, EvoLib.Protocol.ImgLibs.GameInter, 422, 422, 423, , False)
                btnNo = New GUI.MirButton(msg, "btnNo", ((.Image(421).Header.Width \ 4) * 3) - (.Image(426).Header.Width \ 2), 145, 0.01F, EvoLib.Protocol.ImgLibs.GameInter, 426, 426, 427, , False)

            End With

            mMsgBoxes = New Queue

        End Sub

        Private Sub msg_DrawWindow(ByRef mode As Globals.DrawingMode, ByRef x As Integer, ByRef y As Integer, ByRef z As Single) Handles msg.DrawWindow

            If mode = Globals.DrawingMode.Normal Then

                If mMsgBoxes.Count = 0 Then Exit Sub

                With Libs.GameInter


                    .Image(421).Draw(x, y, z)

                End With

            ElseIf mode = Globals.DrawingMode.Text Then

                Dim box As MsgBoxStruct = mMsgBoxes.Peek

                Dim tmp As Rectangle = rText
                tmp.Offset(x, y)
                'DirectX.GameSprite.End()
                DirectX.ProFont9.DrawNormalText(box.mText, tmp, Microsoft.DirectX.Direct3D.DrawTextFormat.Left Or _
                Microsoft.DirectX.Direct3D.DrawTextFormat.ExpandTabs Or _
                Microsoft.DirectX.Direct3D.DrawTextFormat.WordBreak Or _
                Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip, Color.White, z)
                'DirectX.GameSprite.Begin(Microsoft.DirectX.Direct3D.SpriteFlags.AlphaBlend)


            End If

        End Sub

        Public Sub AddMessageBox(ByRef name As String, ByRef text As String, ByRef style As MsgBoxButtons, _
                                    ByRef callback As MsgBoxResultDelegate, Optional ByRef maxinputlen As Integer = 0, _
                                    Optional ByRef maskinput As Boolean = False, Optional ByRef validchars As String = EvoLib.Protocol.VALID_PASSWORD_CHARS)

            Dim struct As New MsgBoxStruct
            With struct
                .mName = name
                .mText = text
                .mButtons = style
                .mDelegate = callback
                .mMaxInputLen = maxinputlen
                .mMaskInput = maskinput
                .mValidChars = validchars
            End With
            mMsgBoxes.Enqueue(struct)

            If mMsgBoxes.Count = 1 Then
                Windows.AddWindow(msg, Windows.WindowType.AlwaysOnTop)
                DoInterface()
            End If

        End Sub

        Private Sub DoResult(ByRef result As MsgBoxResults)

            Dim box As MsgBoxStruct = mMsgBoxes.Dequeue
            Dim ret As MsgBoxResult
            ret.mName = box.mName
            If Not txtInput Is Nothing Then
                ret.mInput = txtInput.Text
            Else
                ret.mInput = ""
            End If
            ret.mResult = result
            If Not box.mDelegate Is Nothing Then box.mDelegate.Invoke(ret)

            If mMsgBoxes.Count > 0 Then
                DoInterface()
            Else
                Windows.RemoveWindow(msg)
            End If

        End Sub

        Private Sub btnOK_Click() Handles btnOK.Click

            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            DoResult(MsgBoxResults.OK)

        End Sub

        Private Sub btnYes_Click() Handles btnYes.Click

            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            DoResult(MsgBoxResults.Yes)

        End Sub

        Private Sub btnNo_Click() Handles btnNo.Click

            Sound.PlaySoundEffect(Sound.GetSoundEffectFile(Sound.SoundEffects.Click), 100)
            DoResult(MsgBoxResults.No)

        End Sub

        Private Sub DoInterface()

            Dim box As MsgBoxStruct = mMsgBoxes.Peek

            If Not txtInput Is Nothing Then
                txtInput.Destroy()
            End If

            If box.mButtons = MsgBoxButtons.OK Then
                btnOK.Visible = True
                btnYes.Visible = False
                btnNo.Visible = False

            ElseIf box.mButtons = MsgBoxButtons.YesNo Then
                btnOK.Visible = False
                btnYes.Visible = True
                btnNo.Visible = True

            ElseIf box.mButtons = MsgBoxButtons.Input Then

                btnOK.Visible = True
                btnYes.Visible = False
                btnNo.Visible = False

                txtInput = New GUI.MirTextBox(msg, "txtInput", 33, 180, box.mMaxInputLen, box.mMaxInputLen, DirectX.ProFont9, box.mMaskInput, , , , box.mValidChars)
                txtInput.SetFixedWidth(232)
                txtInput.SetNormColors(Color.FromArgb(255, 8, 8, 8), Color.FromArgb(255, 8, 8, 8), Color.Gray)
                txtInput.SetFocusedColors(Color.FromArgb(255, 8, 8, 8), Color.Gray, Color.White)
                txtInput.SetCaretColor(Color.Gray)

                'focus to txt input
                Windows.FocusInterface(txtInput)

                'txtInput.SetTextFormat(DrawTextFormat.Center Or DrawTextFormat.NoClip)

            End If

            With Libs.GameInter

                msg.SetPosition((DirectX.DispMode.Width \ 2) - (.Image(421).Header.Width \ 2), (DirectX.DispMode.Height \ 2) - (.Image(421).Header.Height \ 2))

            End With

        End Sub

        Public Function BlockInputs(ByRef wnd As GUI.MirWindow) As Boolean

            If Not sStateNotice Is Nothing Then
                If sStateNotice.Length > 0 Then
                    Return True
                End If
            End If

            If Not msg.Equals(wnd) Then

                If mMsgBoxes.Count = 0 Then
                    Return False
                Else
                    Return True
                End If

            End If

        End Function

        Public Sub SetStateNotice(ByRef text As String)
            AddStateNoticeTimer()
            sStateNotice = text
        End Sub

        Public Sub RemoveStateNotice()
            SetStateNotice(Nothing)
            RemoveStateNoticeTimer()
        End Sub

        Private Const cStateAnimCount As Integer = 6
        Private Const cStateAnimImage As Integer = 601
        Private Const cStateAnimSpeed As Integer = 2500000
        Private bStateTimerAdded As Boolean

        Private Sub AddStateNoticeTimer()
            If Not bStateTimerAdded Then
                Timers.AddTimer("StateNoticeAnim", cStateAnimSpeed, cStateAnimCount - 1)
                bStateTimerAdded = True
            End If
        End Sub

        Private Sub RemoveStateNoticeTimer()
            If bStateTimerAdded Then
                Timers.RemoveTimer("StateNoticeAnim")
                bStateTimerAdded = False
            End If
        End Sub

        Public Sub DrawStateNotice(ByRef mode As Globals.DrawingMode)

            If Not sStateNotice Is Nothing Then
                If sStateNotice.Length > 0 Then

                    With Libs.GameInter

                        If mode = Globals.DrawingMode.Normal Then

                            .Image(664).Draw((DirectX.DispMode.Width \ 2) - (.Image(664).Header.Width \ 2), (DirectX.DispMode.Height \ 2) - (.Image(664).Header.Height \ 2), 0.01)

                        ElseIf mode = Globals.DrawingMode.Text Then

                            Dim tmp As Rectangle = rStateText
                            tmp.Offset((DirectX.DispMode.Width \ 2) - (.Image(664).Header.Width \ 2), (DirectX.DispMode.Height \ 2) - (.Image(664).Header.Height \ 2))
                            DirectX.ProFont9.DrawNormalText(sStateNotice, tmp, Microsoft.DirectX.Direct3D.DrawTextFormat.Left Or _
                            Microsoft.DirectX.Direct3D.DrawTextFormat.ExpandTabs Or _
                            Microsoft.DirectX.Direct3D.DrawTextFormat.WordBreak Or _
                            Microsoft.DirectX.Direct3D.DrawTextFormat.NoClip, Color.White, 0.01)

                        ElseIf mode = Globals.DrawingMode.Magic Then

                            With .Image(cStateAnimImage + Timers.GetTimer("StateNoticeAnim"))
                                .Draw((DirectX.DispMode.Width \ 2) - (Libs.GameInter.Image(664).Header.Width \ 2) + 290 + .Header.OffsetX, (DirectX.DispMode.Height \ 2) - (Libs.GameInter.Image(664).Header.Height \ 2) + 114 + .Header.OffsetY, 0.01)
                            End With

                        End If

                    End With

                End If
            End If

        End Sub

    End Module

End Namespace